﻿// Fill out your copyright notice in the Description page of Project Settings.


#include "Actor/Projectile.h"

#include "AbilitySystemBlueprintLibrary.h"
#include "AbilitySystemComponent.h"
#include "NiagaraFunctionLibrary.h"
#include "AbilitySystem/AuraAbilitySystemBPLibrary.h"
#include "Aura/Aura.h"
#include "Components/AudioComponent.h"
#include "Components/SphereComponent.h"
#include "GameFramework/ProjectileMovementComponent.h"
#include "Kismet/GameplayStatics.h"


AProjectile::AProjectile()
{
	PrimaryActorTick.bCanEverTick = false;
	// 启用复制
	bReplicates = true;

	Sphere = CreateDefaultSubobject<USphereComponent>("Sphere");
	SetRootComponent(Sphere);
	// 设置碰撞为仅查询: 射线、扫描、重叠检测
	Sphere->SetCollisionEnabled(ECollisionEnabled::QueryOnly);
	// 设置对象碰撞响应时是哪种物体类型
	Sphere->SetCollisionObjectType(ECC_PROJECTILE);
	// 设置其忽略所有碰撞响应
	Sphere->SetCollisionResponseToAllChannels(ECR_Ignore);
	// 设置指定碰撞响应,为重叠
	Sphere->SetCollisionResponseToChannel(ECC_WorldDynamic, ECR_Overlap);
	Sphere->SetCollisionResponseToChannel(ECC_WorldStatic, ECR_Overlap);
	Sphere->SetCollisionResponseToChannel(ECC_Pawn, ECR_Overlap);

	ProjectileMovement = CreateDefaultSubobject<UProjectileMovementComponent>("ProjectileMovement");
	ProjectileMovement->InitialSpeed = 550.f;
	ProjectileMovement->MaxSpeed = 550.f;
	ProjectileMovement->ProjectileGravityScale = 0.f;
}


void AProjectile::BeginPlay()
{
	Super::BeginPlay();

	//设置此物体的存在时间
	SetLifeSpan(LifeSpan);


	Sphere->OnComponentBeginOverlap.AddDynamic(this, &AProjectile::OnSphereOverlap);

	// 添加一个音效，并附加到根组件上面，在Actor移动时，声音也会跟随移动
	LoopingSoundComponent = UGameplayStatics::SpawnSoundAttached(LoopingSound, GetRootComponent());
}

void AProjectile::Destroyed()
{
	//如果没有权威性，并且bHit没有修改为true，证明当前没有触发Overlap事件，在销毁前播放击中特效
	// 没有击中别人而声明周期到了进行销毁,则销毁前播放击中特效
	if (!bHit && !HasAuthority())
	{
		PlayAfterImpacted();
		bHit = true;
	}

	Super::Destroyed();
}

void AProjectile::OnSphereOverlap(
	UPrimitiveComponent* OverlappedComponent, AActor* OtherActor, UPrimitiveComponent* OtherComp, int32 OtherBodyIndex,
	bool bFromSweep, const FHitResult& SweepResult
)
{
	// 如果是发起者，则不处理
	if (GetInstigator() == OtherActor)
	{
		return;
	}

	/** 友方不处理 */
	if (UAuraAbilitySystemBPLibrary::IsFriendly(GetInstigator(), OtherActor))
	{
		return;
	}

	// 首次重叠时，播放表现效果
	if (!bHit)
	{
		PlayAfterImpacted();
		bHit = true;
	}

	// 服务端逻辑
	if (HasAuthority())
	{
		// 为目标应用GE
		if (UAbilitySystemComponent* TargetASC = UAbilitySystemBlueprintLibrary::GetAbilitySystemComponent(OtherActor))
		{
			TargetASC->ApplyGameplayEffectSpecToSelf(*DamageEffectHandle.Data.Get());
		}

		// 在重叠后，销毁自身
		Destroy();
	}
}

void AProjectile::PlayAfterImpacted() const
{
	//播放音效
	UGameplayStatics::PlaySoundAtLocation(this, ImpactSFX, GetActorLocation(), FRotator::ZeroRotator);
	//播放粒子特效
	UNiagaraFunctionLibrary::SpawnSystemAtLocation(this, ImpactVFX, GetActorLocation());
	// 组件默认将音乐停止后自动销毁
	if (LoopingSoundComponent)
	{
		LoopingSoundComponent->Stop();
	}
}
